﻿/* EntitiesToDTOs. Copyright (c) 2011. Fabian Fernandez.
 * http://entitiestodtos.codeplex.com
 * Licensed by Common Development and Distribution License (CDDL).
 * http://entitiestodtos.codeplex.com/license
 * Fabian Fernandez. 
 * http://www.linkedin.com/in/fabianfernandezb/en
 * */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EnvDTE;
using EntitiesToDTOs.Enums;
using EntitiesToDTOs.Domain;
using System.Xml.Linq;
using EntitiesToDTOs.Helpers;
using EntitiesToDTOs.Properties;

namespace EntitiesToDTOs.Generators.Parameters
{
    /// <summary>
    /// Parameters for the AssemblerGenerator GenerateAssemblers method.
    /// This is because it is used with BackgroundWorker, we need an object to provide all typed parameters.
    /// </summary>
    internal class GenerateAssemblersParams
    {
        /// <summary>
        /// Project where the Assemblers are going to be generated.
        /// </summary>
        public Project TargetProject { get; set; }

        /// <summary>
        /// [Used only for configuration management] 
        /// Name of the Project where the Assemblers are going to be generated.
        /// </summary>
        public string TargetProjectName { get; set; }

        /// <summary>
        /// Source File Header Comment (optional).
        /// </summary>
        public string SourceFileHeaderComment { get; set; }

        /// <summary>
        /// Indicates if Target Project default namespace is going to be used.
        /// </summary>
        public bool UseProjectDefaultNamespace { get; set; }

        /// <summary>
        /// Namespace used for the Assemblers.
        /// </summary>
        public string SourceNamespace { get; set; }

        /// <summary>
        /// Specifies the Source File Generation Type desired.
        /// </summary>
        public string SourceFileGenerationType
        {
            get
            {
                return _sourceFileGenerationType;
            }
            set
            {
                SourceFileGenerationTypeEnum.Validate(value);
                _sourceFileGenerationType = value;
            }
        }
        private string _sourceFileGenerationType;

        /// <summary>
        /// Source File Name to use if the Source File Generation Type is OneSourceFile.
        /// </summary>
        public string SourceFileName { get; set; }

        /// <summary>
        /// Specifies if it is Service-Ready (serialization is going to be used).
        /// </summary>
        public bool IsServiceReady { get; set; }

        /// <summary>
        /// <see cref="System.Collections.Generic.List{EntityDTO}"/> to generate the Assemblers from.
        /// </summary>
        public List<EntityDTO> EntitiesDTOs { get; set; }

        /// <summary>
        /// DTO's namespace.
        /// </summary>
        public string DTOsNamespace { get; set; }

        /// <summary>
        /// DTO's target Project.
        /// </summary>
        public Project DTOsTargetProject { get; set; }

        /// <summary>
        /// Project containing the EDMX file.
        /// </summary>
        public Project EDMXProject { get; set; }

        /// <summary>
        /// Namespace used for the entities.
        /// </summary>
        public string EntitiesNamespace { get; set; }


        public GenerateAssemblersParams() { }

        /// <summary>
        /// Creates a new instance of <see cref="GenerateAssemblersParams"/>.
        /// </summary>
        /// <param name="targetProject">Project where the Assemblers are going to be generated.</param>
        /// <param name="sourceFileHeaderComment">Source File Header Comment (optional).</param>
        /// <param name="useProjectDefaultNamespace">Indicates if Target Project default namespace is going to be used.</param>
        /// <param name="sourceNamespace">Namespace used for the Assemblers.</param>
        /// <param name="sourceFileGenerationType">Specifies the Source File Generation Type desired.</param>
        /// <param name="sourceFileName">Source File Name to use if the Source File Generation Type is OneSourceFile.</param>
        /// <param name="isServiceReady">Specifies if the DTOs are Service-Ready (this means if they can be serialized or not).</param>
        /// <param name="dtosNamespace">DTO's namespace.</param>
        /// <param name="dtosTargetProject">DTO's target Project.</param>
        /// <param name="edmxProjectItem">EDMX ProjectItem.</param>
        public GenerateAssemblersParams(Project targetProject, string sourceFileHeaderComment, 
            bool useProjectDefaultNamespace, string sourceNamespace, string sourceFileGenerationType,
            string sourceFileName, bool isServiceReady, string dtosNamespace, Project dtosTargetProject,
            ProjectItem edmxProjectItem)
        {
            this.TargetProject = targetProject;
            this.SourceFileHeaderComment = sourceFileHeaderComment;
            this.UseProjectDefaultNamespace = useProjectDefaultNamespace;
            this.SourceNamespace = sourceNamespace;
            this.SourceFileGenerationType = sourceFileGenerationType;
            this.SourceFileName = sourceFileName;
            this.IsServiceReady = isServiceReady;
            this.DTOsNamespace = dtosNamespace;
            this.DTOsTargetProject = dtosTargetProject;
            this.EDMXProject = edmxProjectItem.ContainingProject;

            #region Set EntitiesNamespace
            // Get ProjectItem EDMX.Designer where Entities are coded
            ProjectItem edmxDesigner = edmxProjectItem.ProjectItems.Item(1);

            bool namespaceFound = false;

            // Loop CodeElements, find and set Entities namespace
            foreach (CodeElement element in edmxDesigner.FileCodeModel.CodeElements)
            {
                if (element.Kind == vsCMElement.vsCMElementNamespace)
                {
                    this.EntitiesNamespace = (element as CodeNamespace).Name;
                    namespaceFound = true;
                    break;
                }
            }

            if (namespaceFound == false)
            {
                throw new Exception(string.Format(Resources.Error_EntitiesNamespaceNotFound, edmxDesigner.Name));
            }
            #endregion Set EntitiesNamespace
        }
    }
}